package com.hospitalmanagementsystem.service.impl;

import com.hospitalmanagementsystem.dto.UserDTO;
import com.hospitalmanagementsystem.dto.UserProfileUpdateRequestDTO;
import com.hospitalmanagementsystem.entity.User;
import com.hospitalmanagementsystem.entity.Role;
import com.hospitalmanagementsystem.repository.UserRepository;
import com.hospitalmanagementsystem.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    @Autowired
    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional(readOnly = true)
    public UserDTO getUserProfile(String username) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));
        return convertToDTO(user);
    }

    @Override
    @Transactional
    public UserDTO updateUserProfile(String username, UserProfileUpdateRequestDTO profileUpdateRequestDTO) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));

        if (profileUpdateRequestDTO.getEmail() != null && !profileUpdateRequestDTO.getEmail().isEmpty()) {
            // Consider adding email format validation if not handled elsewhere
            user.setEmail(profileUpdateRequestDTO.getEmail());
        }
        if (profileUpdateRequestDTO.getPhoneNumber() != null) {
            user.setPhoneNumber(profileUpdateRequestDTO.getPhoneNumber());
        }
        if (profileUpdateRequestDTO.getFullName() != null && !profileUpdateRequestDTO.getFullName().isEmpty()) {
            user.setFullName(profileUpdateRequestDTO.getFullName());
        }
        if (profileUpdateRequestDTO.getAddress() != null) {
            user.setAddress(profileUpdateRequestDTO.getAddress());
        }
        if (profileUpdateRequestDTO.getDateOfBirth() != null && !profileUpdateRequestDTO.getDateOfBirth().isEmpty()) {
            try {
                user.setDateOfBirth(LocalDate.parse(profileUpdateRequestDTO.getDateOfBirth(), DateTimeFormatter.ISO_LOCAL_DATE));
            } catch (Exception e) {
                // Log error and potentially throw a custom exception for bad date format
                System.err.println("Error parsing date of birth: '" + profileUpdateRequestDTO.getDateOfBirth() + 
                    "'. Expected format: yyyy-MM-dd. Error: " + e.getMessage());
                // For a production app, you might throw a BadRequestException here
            }
        }

        User updatedUser = userRepository.save(user);
        return convertToDTO(updatedUser);
    }

    private UserDTO convertToDTO(User user) {
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setEmail(user.getEmail());
        userDTO.setPhoneNumber(user.getPhoneNumber());
        userDTO.setFullName(user.getFullName());
        userDTO.setAddress(user.getAddress());
        if (user.getDateOfBirth() != null) {
            userDTO.setDateOfBirth(user.getDateOfBirth().format(DateTimeFormatter.ISO_LOCAL_DATE));
        }
        if (user.getRoles() != null) {
            userDTO.setRoles(user.getRoles().stream().map(Role::getName).collect(Collectors.toList()));
        } else {
            userDTO.setRoles(java.util.Collections.emptyList()); // Ensure roles list is never null
        }
        return userDTO;
    }
} 